home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / strategy / xpuzzles.3 / xpuzzles / xpuzzles-5.3.1 / xhexagons / HexagonsU.c < prev    next >
C/C++ Source or Header  |  1996-02-05  |  7KB  |  280 lines

  1. /*
  2. # X-BASED HEXAGONS
  3. #
  4. #  HexagonsU.c
  5. #
  6. ###
  7. #
  8. #  Copyright (c) 1994 - 96    David Albert Bagley, bagleyd@hertz.njit.edu
  9. #
  10. #                   All Rights Reserved
  11. #
  12. #  Permission to use, copy, modify, and distribute this software and
  13. #  its documentation for any purpose and without fee is hereby granted,
  14. #  provided that the above copyright notice appear in all copies and
  15. #  that both that copyright notice and this permission notice appear in
  16. #  supporting documentation, and that the name of the author not be
  17. #  used in advertising or publicity pertaining to distribution of the
  18. #  software without specific, written prior permission.
  19. #
  20. #  This program is distributed in the hope that it will be "playable",
  21. #  but WITHOUT ANY WARRANTY; without even the implied warranty of
  22. #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  23. #
  24. */
  25.  
  26. /* Undo algorithm */
  27.  
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <X11/IntrinsicP.h>
  31. #include <X11/Intrinsic.h>
  32. #include <X11/StringDefs.h>
  33. #include <X11/CoreP.h>
  34. #include "HexagonsP.h"
  35.  
  36. typedef struct _MoveRecord
  37. {
  38.   /* int direction; */
  39.   unsigned char packed; /* This makes assumptions on the data. */
  40. } MoveRecord;
  41.  
  42. typedef struct _MoveStack
  43. {
  44.   MoveRecord move;
  45.   struct _MoveStack *previous, *next;
  46. } MoveStack;
  47.  
  48. static MoveStack *currMove, *lastMove, *firstMove;
  49. static int count;
  50. static int startSpace[SPACES];
  51. static int startRow[ROWTYPES];
  52. int *startPosition = NULL;
  53.  
  54. static void InitStack();
  55. static void PushStack();
  56. static void PopStack();
  57. static int EmptyStack();
  58. static void FlushStack();
  59.  
  60. static void InitStack()
  61. {
  62.   if (!(lastMove = (MoveStack *) malloc(sizeof(MoveStack))))
  63.     XtError("Not enough memory, exiting.");
  64.   if (!(firstMove = (MoveStack *) malloc(sizeof(MoveStack))))
  65.     XtError("Not enough memory, exiting.");
  66.   firstMove->previous = lastMove->next = NULL;
  67.   firstMove->next = lastMove;
  68.   lastMove->previous = firstMove;
  69.   count = 0;
  70. }
  71.  
  72. static void PushStack(move)
  73.   MoveRecord move;
  74. {
  75.   if (!(currMove = (MoveStack *) malloc(sizeof(MoveStack))))
  76.     XtError("Not enough memory, exiting.");
  77.   lastMove->previous->next = currMove;
  78.   currMove->previous = lastMove->previous;
  79.   currMove->next = lastMove;
  80.   lastMove->previous = currMove;
  81.   currMove->move = move;
  82.   count++;
  83. }
  84.  
  85. static void PopStack(move)
  86.   MoveRecord *move;
  87. {
  88.   *move = lastMove->previous->move;
  89.   currMove = lastMove->previous;
  90.   lastMove->previous->previous->next = lastMove;
  91.   lastMove->previous = lastMove->previous->previous;
  92.   (void) free((void *) currMove);
  93.   count--;
  94. }
  95.  
  96. static int EmptyStack()
  97. {
  98.   return (lastMove->previous == firstMove);
  99. }
  100.  
  101. static void FlushStack()
  102. {
  103.   while (lastMove->previous != firstMove) {
  104.     currMove = lastMove->previous;
  105.     lastMove->previous->previous->next = lastMove;
  106.     lastMove->previous = lastMove->previous->previous;
  107.     (void) free((void *) currMove);
  108.   }
  109.   count = 0;
  110. }
  111.  
  112. /**********************************/
  113.  
  114. void InitMoves()
  115. {
  116.   InitStack();
  117. }
  118.  
  119. static void WriteMove(move, direction)
  120.   MoveRecord *move;
  121.   int direction;
  122. {
  123.   /* move->direction = direction; */
  124.   move->packed = direction & 0xF;
  125. }
  126.  
  127. static void ReadMove(direction, move)
  128.   int *direction;
  129.   MoveRecord move;
  130. {
  131.   /* *direction = move.direction; */
  132.   *direction = move.packed & 0xF;
  133. }
  134.  
  135. void PutMove(direction)
  136.   int direction;
  137. {
  138.   MoveRecord move;
  139.  
  140.   WriteMove(&move, direction);
  141.   PushStack(move);
  142. }
  143.  
  144. void GetMove(direction)
  145.   int *direction;
  146. {
  147.   MoveRecord move;
  148.  
  149.   PopStack(&move);
  150.   ReadMove(direction, move);
  151. }
  152.  
  153. int MadeMoves()
  154. {
  155.   return !EmptyStack();
  156. }
  157.  
  158. void FlushMoves(w)
  159.   HexagonsWidget w;
  160. {
  161.   int i;
  162.  
  163.   FlushStack();
  164.   startSpace[LOW] = w->hexagons.spacePosition[LOW];
  165.   startSpace[HIGH] = w->hexagons.spacePosition[HIGH];
  166.   startRow[TRBL] = w->hexagons.spaceRow[TRBL];
  167.   startRow[TLBR] = w->hexagons.spaceRow[TLBR];
  168.   startRow[ROW] = w->hexagons.spaceRow[ROW];
  169.   for (i = 0; i < w->hexagons.sizeSize; i++)
  170.     startPosition[i] = w->hexagons.tileOfPosition[i];
  171. }
  172.  
  173. int NumMoves()
  174. {
  175.   return count;
  176. }
  177.  
  178. void ScanMoves(fp, w, moves)
  179.   FILE *fp;
  180.   HexagonsWidget w;
  181.   int moves;
  182. {
  183.   int direction, l;
  184.   char c;
  185.  
  186.   for (l = 0; l < moves; l++) {
  187.     while ((c = getc(fp)) != EOF && c != SYMBOL);
  188.     (void) fscanf(fp, "%d", &direction);
  189.     if (!MoveHexagonsDir(w, direction))
  190.       (void) fprintf(fp, "%d move in direction %d, can not be made.",
  191.         l, direction);
  192.   }
  193. }
  194.  
  195. void PrintMoves(fp)
  196.   FILE *fp;
  197. {
  198.   int direction, counter = 0;
  199.  
  200.   currMove = firstMove->next;
  201.   (void) fprintf(fp, "moves\tdir\n"); 
  202.   while (currMove != lastMove) {
  203.     ReadMove(&direction, currMove->move);
  204.     (void) fprintf(fp, "%d%c\t%d\n", ++counter, SYMBOL, direction); 
  205.     currMove = currMove->next;
  206.   }
  207. }
  208.  
  209. void ScanStartPosition(fp, w)       
  210.   FILE *fp;
  211.   HexagonsWidget w;
  212. {
  213.   int i, num;
  214.   char c;
  215.  
  216.   while ((c = getc(fp)) != EOF && c != SYMBOL);
  217.   for (i = 0; i < w->hexagons.sizeSize; i++) {
  218.     (void) fscanf(fp, "%d ", &num);
  219.     startPosition[i] = num;
  220.     if (!num)
  221.       startSpace[HIGH] = i;
  222.     else if (num == -1)
  223.       startSpace[LOW] = i;
  224.   }
  225.   if (w->hexagons.corners) {
  226.     startRow[HIGH] = Row(w, startSpace[HIGH]);
  227.     if (w->hexagons.size > 1)
  228.       startRow[LOW] = Row(w, startSpace[LOW]);
  229.   } else {
  230.     startRow[ROW] = Row(w, startSpace[HIGH]);
  231.     startRow[TRBL] = TrBl(w, startSpace[HIGH], startRow[ROW]);
  232.     startRow[TLBR] = TlBr(w, startSpace[HIGH], startRow[ROW]);
  233.   }
  234. }
  235.  
  236. void PrintStartPosition(fp, w)       
  237.   FILE *fp;
  238.   HexagonsWidget w;
  239. {
  240.   int rowPos = 0, r = 0, rp, p, length = 0;
  241.  
  242.   (void) fprintf(fp, "\nstartingPosition%c\n", SYMBOL);
  243.   for (p = 0; p < w->hexagons.sizeSize; p++) {
  244.     if (rowPos == 0) {
  245.       if (p < w->hexagons.sizeSize / 2) /* CENTER */ {
  246.         length = w->hexagons.size + r;
  247.         for (rp = 0; rp < w->hexagons.size - 1 - r; rp++)
  248.           (void) fprintf(fp, "  ");
  249.       } else {
  250.         length = 3 * w->hexagons.size - r - 2;
  251.         for (rp = 0; rp < r - w->hexagons.size + 1; rp++)
  252.           (void) fprintf(fp, "  ");
  253.       }
  254.     }
  255.     (void) fprintf(fp, "%3d ", startPosition[p]);
  256.     if (rowPos == length - 1) {
  257.       r++;
  258.       rowPos = 0;
  259.       (void) fprintf(fp, "\n");
  260.     } else
  261.       rowPos++;
  262.   }
  263.   (void) fprintf(fp, "\n");
  264. }
  265.  
  266. void SetStartPosition(w)       
  267.   HexagonsWidget w;
  268. {
  269.   int i;
  270.  
  271.   w->hexagons.spacePosition[HIGH] = startSpace[HIGH];
  272.   w->hexagons.spacePosition[LOW] = startSpace[LOW];
  273.   w->hexagons.spaceRow[TRBL] = startRow[TRBL];
  274.   w->hexagons.spaceRow[TLBR] = startRow[TLBR];
  275.   w->hexagons.spaceRow[ROW] = startRow[ROW];
  276.   for (i = 0; i < w->hexagons.sizeSize; i++)
  277.     w->hexagons.tileOfPosition[i] = startPosition[i];
  278.   DrawAllTiles(w, w->hexagons.tileGC, w->hexagons.borderGC);
  279. }
  280.